import { loadToml } from "./toml";
import { treeMap } from "./tree";
import LayoutEmpty from "../layout/empty/index.vue";
import LayoutBase from "../layout/base/index.vue";
import { RouteMeta,Router,RouteLocationNormalizedLoaded } from "vue-router";
import { Component } from "vue";
import http from "../axios"
import { replaceObj } from "./temp";
import get from "lodash/get"
//
const PAGES = import.meta.glob("@/views/**/*.vue");
const PATHS = Object.keys(PAGES);
const NAMES = PATHS.map((k) =>
  k.replace(/.*?views\//, "").replace(/\.vue$/, "")
);

//
export interface RouteData {
  name: string;
  path: string;
  redirect?: string;
  component?: string;
  meta?: string;
  children?: RouteData[];
  parentName?: string;
}
//
const routeCache:Record<string,any[]> = {}
//
const addRoute = (data: any, parentName = "",router:Router) => {
  const d = {...data}
  const c = data.component;
  if (c) {
    const i = NAMES.indexOf(c);
    let component: Component = LayoutBase;
    switch (c) {
      case "Base":
        component = LayoutBase;
        break;
      case "Empty":
        component = LayoutEmpty;
        break;
      default:
        component = i != -1 ? PAGES[PATHS[i]] : LayoutEmpty;
    }
    d.component = component;
  }
  if(parentName){
    if(router.hasRoute(parentName)){
      router.addRoute(parentName, d)
    }else{
      routeCache[parentName] = new Array<any>().concat((routeCache[parentName] || []),d)
    }
  }else{
    router.addRoute(d)
    if(routeCache[d.name] && routeCache[d.name].length > 0){
      let td:any;
      while((td = routeCache[d.name].pop()) != undefined){
        router.addRoute(d.name,td);
      }
    }
  }
};
// 动态路由 routes 是扁平数据结构 树形结构也支持
export const addRoutes = (routes: (RouteData & { ct?: number })[],router:Router) => {
  const cache: (RouteData & { ct?: number })[] = [];
  routes.forEach((n) => {
    const {
      name,
      path,
      parentName,
      children,
      redirect = "",
      meta: m,
      ct = 0,
    } = n;
    if (ct > 10) {
      console.error("路由追加失败！重试次数超限！ ===> ", n);
      return;
    }
    if (parentName && !router.hasRoute(parentName)) {
      cache.push({ ...n, ct: ct + 1 });
      return;
    }
    if (router.hasRoute(name)) {
      return;
    }
    if (children && children.length > 0) {
      cache.push(...children.map((d) => ({ ...d, parentName: name })));
    }
    const component = n.component ?? path ?? "";
    let meta: RouteMeta = {};
    try {
      if (m) {
        meta = JSON.parse(m);
      }
    } catch (error) {
      console.error("==== 路由 meta 解析失败！=====", m);
    }
    const data = { name, path, redirect, meta, component };
    addRoute(data, parentName,router);
  });
  if (cache.length > 0) {
    addRoutes(cache,router);
  }
};

export const addRouteTree = (routes: RouteData[],router:Router) => {
  treeMap(routes, (n, l, ins, p) => {
    const { name, path, redirect = "", meta: m } = n;
    if (router.hasRoute(name)) {
      return;
    }
    const component = n.component ?? path ?? "";
    let meta: RouteMeta = {};
    try {
      if (m) {
        meta = JSON.parse(m);
      }
    } catch (error) {
      console.error("==== 路由 meta 解析失败！=====", m);
    }
    const data = { name, path, redirect, meta, component };
    const pName = p?.name;
    addRoute(data,pName,router);
  });
};

export const getRoutes = async (apiConfig:any) => {
  const attr = replaceObj(apiConfig.http)
  //
  try {
    const res = await http(attr);
    //
    return get(res,attr.value) || []
  } catch (error) {
    return []
  }
}

// 路由菜单数据初始化
export const initRoutes = async ({router,route,store}:any) => {
  // routeCache = {}
  const RD: any = await loadToml("routes.toml");
  //
  const {
    homePath,
    routes,
    basePath,
    baseComponent,
    autoRedirct,
    autoSort,
    sortKey,
    sortVal,
    api
  } = RD;
  // 判断是否使用接口
  const rts = api.enabled ? await getRoutes(api) : routes;
  //
  if (rts && rts.length > 0) {
    const menu = treeMap(rts, (n, l, i, pn) => {
      const {
        name,
        path,
        component = baseComponent,
        meta,
        redirect,
        type = "11",
      } = n;
      
      const [mt, rt] = type.split("").map((v:string) => Number(v));
      // 添加路由
      const d: any = {};
      if (name) {
        d.name = name;
      }
      if (path) {
        d.path =
          /^\//.test(path) && pn == undefined
            ? path
            : pn
            ? `${pn.path}/${path}`
            : `${basePath}/${path}`;
        n.path = d.path;
      } else {
        return;
      }
      if (component) {
        d.component = component
      }
      if (meta) {
        d.meta = meta;
      }
      if (redirect) {
        d.redirect = redirect;
      }
      //
      if (rt == 1 && !router.hasRoute(name)) {
        addRoute(d,pn?.name,router)
      }
      if (mt == 0) {
        const it = l.indexOf(n);
        l.splice(it, 1);
      }
      if (autoSort && l) {
        l.sort(
          (a, b) =>
            (a[sortKey] == undefined ? sortVal : a[sortKey]) -
            (b[sortKey] == undefined ? sortVal : b[sortKey])
        );
      }
    });
    store.commit("setMenus", menu);
  }
  // 自动跳转
  if (autoRedirct && route.query.redirect) {
    const redirect = route.query.redirect as string;
    router.push({ path: redirect });
  } else if (route.path == "/") {
    router.push({ path: homePath });
  }else{
    router.push({path:route.path})
  }
};
